# state-model

Модель состояния - DSL модели объекта и формы, поддержка шаблона MVC

## Пример описания параметров состояния

```
Функция МодельСостояния(Контекст) Экспорт
	Если ТипЗнч(Контекст) = Тип("ФормаКлиентскогоПриложения") Тогда
		ПутьКДаннымОбъекта = "Объект";
	Иначе
		ПутьКДаннымОбъекта = "";
	КонецЕсли;
	МодельСостояния = Общий.МодельСостояния(Контекст, "_ДемоМодельЗаявкаНаОперацию", ПутьКДаннымОбъекта)
	;
	//  Параметры состояния
	///////////////////////////////////////////////////////////
	МодельСостояния.ПараметрСостояния("ТипОперации")
		.Параметр("ВидОперации")
		.Выражение("ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Параметры.ВидОперации, 'ТипОперацииБюджетирование')")
	;
	МодельСостояния.ПараметрСостояния("ЭтоВнутренняяОперация").ТипБулево()
		.Параметр("ТипОперации")
		.Выражение("(Ложь
		|	ИЛИ Параметры.ТипОперации = ПредопределенноеЗначение('Перечисление._ДемоТипыОперацийБюжетирование.ПеремещениеМеждуМестамиХраненияСредств')
		|	ИЛИ Параметры.ТипОперации = ПредопределенноеЗначение('Перечисление._ДемоТипыОперацийБюжетирование.КонвертацияВалюты')
		|)")
	;
	МодельСостояния.ПараметрСостояния("ЭтоВнешняяОперация").ТипБулево()
		.Параметр("ЭтоВнутренняяОперация")
		.Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
	;
	МодельСостояния.ПараметрСостояния("БанковскийСчет")
		.Параметр("Отбор.Владелец", "Организация")
	;//  Счет контрагента имеет двойное подчинение: для внутренней операции - владелец Организация, для внешней - Контрагент
	МодельСостояния.ПараметрСостояния("СчетКонтрагента")
		.Параметр("Отбор.Владелец", "Организация")
			.Использование("ЭтоВнутренняяОперация")
		.Параметр("Отбор.Владелец", "Контрагент")
			.Использование("ЭтоВнешняяОперация")
	;
	МодельСостояния.ПараметрСостояния("ДоговорКонтрагента")
		.Использование("ЭтоВнешняяОперация")
		.Параметр("Отбор.Организация", "Организация")
		.Параметр("Отбор.Владелец", "Контрагент")
	;
	МодельСостояния.ПараметрСостояния("ВалютаВзаиморасчетов")
		.Параметр("ДоговорКонтрагента").Слабая()
		.Выражение("?(Параметры.Свойство('ДоговорКонтрагента'), ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Параметры.ДоговорКонтрагента, 'ВалютаРасчетов'), Значение)")
	;
	МодельСостояния.ПараметрСостояния("Контрагент")
		.Использование("ЭтоВнешняяОперация")
	;//  Вызов обработчика по-умолчанию из модуля модели (см. конструктор модели)
	МодельСостояния.ПараметрСостояния("СуммаВзаиморасчетов").НаКлиенте()
		.ПриИзменении()
	;
	МодельСостояния.ПараметрСостояния("СуммаДокумента").НаКлиенте()
		.Параметр("СуммаВзаиморасчетов")
		.Параметр("КурсРасчетов")
		.Выражение("Параметры.СуммаВзаиморасчетов * Параметры.КурсРасчетов")
	;
	МодельСостояния.ПараметрСостояния("ДвиженияОперации.СуммаВзаиморасчетов").НаКлиенте()
		.Параметр("Сумма", "ДвиженияОперации.Сумма")
		.Параметр("КурсРасчетов")
		.Выражение("Параметры.Сумма * Параметры.КурсРасчетов")
	;
	МодельСостояния.ПараметрСостояния("ЭтоНовый").НаКлиенте()
		.Параметр("Ссылка", , Ложь)
		.Выражение("НЕ ЗначениеЗаполнено(Параметры.Ссылка)")
	;
	Возврат МодельСостояния;
КонецФункции
```

## Пример описания элементов формы

```
	//  МодельСостояния
	//  Конструирование модели состояния
	МодельСостояния = Документы._ДемоЗаявкаНаОперацию.МодельСостояния(ЭтотОбъект);
	//  Элементы формы
	///////////////////////////////////////////////////////////
	МодельСостояния.ЭлементФормы()
		.Свойство("Заголовок")
			.Параметр("Дата")
			.Параметр("Номер")
			.Параметр("Проведен")
			.Параметр("ПометкаУдаления")
			.Параметр("ЭтоНовый")
			.Выражение("СтрШаблон('Заявка на операцию %1 от %2. %3', Параметры.Номер, Параметры.Дата, 
			|	?(Параметры.Проведен, 'Проведен', 
			|		?(Параметры.ПометкаУдаления, 'Помечен на удаление', 
			|			?(Параметры.ЭтоНовый, 'Новый', 'Записан')
			|		)
			|	)
			|)
			|")
	;
	МодельСостояния.ЭлементФормы("ВалютаДокумента")
		.Свойство("Видимость")
			.Параметр("ВалютаВзаиморасчетов")
			.Параметр("ВалютаДокумента")
			.Выражение("Параметры.ВалютаВзаиморасчетов <> Параметры.ВалютаДокумента")
	;
	МодельСостояния.ЭлементФормы("ГруппаКонвертацияРасчетов")
		.Свойство("Видимость")
			.Параметр("ЭтоВнутренняяОперация")
			.Выражение("Параметры.ЭтоВнутренняяОперация")
	;
	МодельСостояния.ЭлементФормы("ГруппаРеквизитыКонтрагента")
		.Свойство("Видимость")
			.Параметр("ЭтоВнутренняяОперация")
			.Выражение("НЕ Параметры.ЭтоВнутренняяОперация")
	;
	//  Инициализация модели объекта
	МодельСостояния.ПрименитьМодель();
	ОбновитьФормуНаСервере();
	//  Конец МодельСостояния
```

## Диаграмма последовательности MVC

![Диаграмма последовательности MVC](https://github.com/KalyakinAG/state-model/blob/main/doc/mvc-seq-diagram.svg)

## Модель данных

![Модель данных](https://github.com/KalyakinAG/state-model/blob/main/doc/data-model.svg)

## Цикл расчета параметров состояния

![Цикл расчета параметров состояния](https://github.com/KalyakinAG/state-model/blob/main/doc/object-model-calc.svg)

## Цикл расчета элементов формы

![Цикл расчета элементов формы](https://github.com/KalyakinAG/state-model/blob/main/doc/form-model-calc.svg)
